﻿using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Kanban.BLLContainer;
using Kanban.Common;
using Kanban.IBLL;
using Kanban.Model;
using KanbanApi.Component;
using KanbanApi.Models;
using KanbanApi.Models.Auth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;

namespace KanbanApi.Controllers
{
    public class AuthController : ApiController
    {
        private readonly IUserService UserService = Container.Resolve<IUserService>();
        private readonly ISys_MenusService Sys_MenusService = Container.Resolve<ISys_MenusService>();

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="request">请求实体</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<LoginResult> Login([FromBody]LoginRequest request)
        {
            LoginResult rs = new LoginResult();
            Data data = new Data();
            UserId_仓码对应表 user = await UserService.GetModelAsync(request.Name, request.Password);
            if (user != null)
            {
                UserModel info = new UserModel { Id = user.Id, name = user.UserName, Roles = user.Roles.Split(',').ToList() };
                try
                {
                    data.token = JwtHelper.GetToken(info);
                    data.user = info;
                    data.expireAt = DateTime.Now.AddDays(1);
                    rs.Message = "登陆成功";
                    rs.Success = true;
                    rs.data = data;
                }
                catch (Exception ex)
                {
                    rs.Message = ex.Message;
                    rs.Success = false;
                }
            }
            else
            {
                rs.Message = "账户或密码错误";
                rs.Success = false;
            }
            return rs;
        }
        [HttpGet]
        [ApiAuthorize]
        [Route("api/routes")]
        public async Task<RouteData.Routes> GenerateRouters()
        {
            var currentUser = (UserModel)RequestContext.RouteData.Values.FirstOrDefault().Value;

            List<RouteData.RouteItem> children = await RouteTreeLoad(currentUser.Roles);
            RouteData.Routes mockRouters = new RouteData.Routes()
            {
                data = new List<RouteData.RouteItem>
                {
                    new RouteData.RouteItem
                    {
                        router = "root",
                        children =  children
                    }
                }
            };

            return mockRouters;
        }

        private async Task<List<RouteData.RouteItem>> RouteTreeLoad(List<string> roles)
        {
            IList<Sys_Menus> menus = await Sys_MenusService.GetAll();

            IList<Sys_Menus> parentRouteData = menus.Where(r => r.MenuParentId == 0).OrderBy(m => m.Sort).ToList();

            List<RouteData.RouteItem> routeData = new List<RouteData.RouteItem>();

            foreach (RouteData.RouteItem item in parentRouteData.Select(m => new RouteData.RouteItem
            {
                router = m.MenuPageUrl,
                id = m.Id,
                children = new List<RouteData.RouteItem>()
            }))
            {
                RouteChildListLoad(item, roles, menus);
                if (item.children.Count > 0 || item.router == "home")
                {
                    routeData.Add(item);
                }
            }
            return routeData;
        }

        private void RouteChildListLoad(RouteData.RouteItem sItem, List<string> roles, IList<Sys_Menus> cacheRouteData)
        {

            List<Sys_Menus> childRoutes;
            if(roles.Any(item=> item == "*"))
            {
                childRoutes = cacheRouteData.Where(r => r.MenuParentId == sItem.id).OrderBy(s => s.Sort).ToList();
            }
            else
            {
                childRoutes = cacheRouteData.Where(r => r.MenuParentId == sItem.id && roles.Contains(r.MenuPageUrl)).OrderBy(s => s.Sort).ToList();
            }
            foreach (RouteData.RouteItem item in childRoutes.Select(item => new RouteData.RouteItem
            {
                id = item.Id,
                router = item.MenuPageUrl,
                name = item.MenuName,
                children = new List<RouteData.RouteItem>(),
                authority = "*"
            }))
            {
                RouteChildListLoad(item, roles, cacheRouteData);
                sItem.children.Add(item);
            }
        }

        [HttpPost]
        [Route("api/agv/agvCallbackService/agvCallback")]
        public ResultModel Demo([FromBody] AgvRequest request)
        {
            //是否继续等待
            if (request.method == "applyBin")
            {
                return new ResultModel
                {
                    code = "1",
                    message = "等待",
                    reqCode = request.reqCode
                };
            }
            ////是否可放箱
            //if (request.method == "applyFromAgv")
            //{
            //    return new ResultModel
            //    {
            //        code = "99",
            //        message = "不可放箱",
            //        reqCode = request.reqCode
            //    };
            //}
            ////是否可取箱
            //if (request.method == "applyToAgv")
            //{
            //    return new ResultModel
            //    {
            //        code = "99",
            //        message = "不可取",
            //        reqCode = request.reqCode
            //    };
            //}

            var model = new ResultModel
            {
                code = "0",
                message = "成功",
                reqCode = request.reqCode
            };
            return model;
        }
    }

    public class ResultModel
    {
        public string code { get; set; }
        public string message { get; set; }
        public string reqCode { get; set; }
    }

    public class AgvRequest
    {
        public string reqCode { get; set; }
        public string cooX { get; set; }
        public string cooY { get; set; }
        public string currentPositionCode { get; set; }
        public string data { get; set; }
        public string mapCode { get; set; }
        public string mapDataCode { get; set; }
        public string method { get; set; }
        public string podCode { get; set; }
        public string podDir { get; set; }
        public string robotCode { get; set; }
        public string taskCode { get; set; }
        public string wbCode { get; set; }
        public string AppId { get; set; }
        public DateTime reqTime { get; set; }
    }
}
